﻿using System.Collections.Specialized;
using System.Configuration;

namespace JetBlack.FeedBus.ExcelAddin
{
    internal static class AssemblyEnvironment
    {
        private static NameValueCollection _appSettings = null;
        public static NameValueCollection AppSettings
        {
            get
            {
                if (_appSettings == null)
                    _appSettings = FetchAppSettings();
                return _appSettings;
            }
        }

        /// <summary>
        /// Either return the assembly local app settings, or if this is not
        /// present the executing one.
        /// </summary>
        /// <returns>The app settings presented in the same format as the configuration manager.</returns>
        private static NameValueCollection FetchAppSettings()
        {
            var config = ReadAssemblyConfig();
            if (config == null || config.AppSettings == null)
                return ConfigurationManager.AppSettings;
            else
                return config.AppSettings.Settings.ToNameValueCollection();
        }

        /// <summary>
        /// The configuration manager presents app settings as a name value collection, but
        /// the get delivered from the configuration object as a key value configuration
        /// collection. This method does the transformation.
        /// </summary>
        /// <param name="collection">The app settings collection off the configuration object.</param>
        /// <returns>A collection of the same type as the one the configuration manager returns.</returns>
        private static NameValueCollection ToNameValueCollection(this KeyValueConfigurationCollection collection)
        {
            var nameValueCollection = new NameValueCollection();
            foreach (KeyValueConfigurationElement setting in collection)
                nameValueCollection.Add(setting.Key, setting.Value);
            return nameValueCollection;
        }

        /// <summary>
        /// This is a method of reading a configuration file associated with a class assembly.
        /// </summary>
        /// <returns>Either the configuration, or null if there was none.</returns>
        private static Configuration ReadAssemblyConfig()
        {
            try
            {
                return ConfigurationManager.OpenExeConfiguration(typeof(AssemblyEnvironment).Assembly.Location);
            }
            catch
            {
                return null;
            }
        }
    }
}
